#ifndef __EVENTLOOP_HPP__
#define __EVENTLOOP_HPP__

#include "Acceptor.hpp"
#include "TcpConnection.hpp"
#include "MySQLClient.hpp"

#include <functional>
#include <map>
#include <vector>
#include <memory>
#include <mutex>
using std::shared_ptr;
using std::map;
using std::vector;
using std::function;
using std::mutex;

namespace wd{

    using TcpConnectionptr = shared_ptr<TcpConnection>;
    using CallBack = function<void(TcpConnectionptr)>; 
    using Functor = function<void()>;

class EventLoop{
public:
    EventLoop(Acceptor &);
    void loop();
    void unloop();
    void setAllCallbacks(const CallBack & onNewConnection
                         ,const CallBack & onMessage
                         ,const CallBack & onClose);

    void addFunctor(Functor &&);
    
    bool mysql_writeQuery(const string & sql);
    vector<vector<string>> mysql_readQuery(const string & sql);
    
private:
    int epollcreate();

    void waitEpollfd();

    void handleNewConnection();
    void handleMessage(int fd);

    void addEpollReadEvent(int clientfd);
    void delEpollReadEvent(int clientfd);

    int eventfdCreate();
    void wakeup();
    void handleReadEvent();
    void doPendingFunctors();
    
    void mysql_init();


private:
    int _epfd;
    Acceptor & _acceptor; 
    bool _isLooping;
    vector<struct epoll_event> _events;
    map<int,TcpConnectionptr> _conns;

    CallBack _onNewConnection;
    CallBack _onMassage;
    CallBack _onClose;

    int _eventfd;
    vector<Functor> _pendingFunctors;
    mutex _mutex;

    MySQLClient _mysql;
};

}


#endif // __EVENTLOOP_HPP__

